package com.example.demo.controller.game;

import com.example.demo.controller.Result;
import com.example.demo.entity.Code;
import com.example.demo.entity.User;
import com.example.demo.game.GameMgrInterface;
import com.example.demo.game.plane.PlaneGameMgr;
import com.example.demo.repository.UserRepository;
import com.example.demo.runner.GameRunner;
import com.example.demo.tool.FileTool;
import com.example.demo.tool.Global;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@CrossOrigin
@RestController
@RequestMapping("/code")
public class CodeCtrl {
    @Resource
    private UserRepository userRepository;

    @PostMapping("/submit")
    public Result submit(@RequestBody Code code) {
        String path = Global.CODE_PATH + code.gameName + "/";
        FileTool.mkDir(path);
        String language = "";
        switch (code.language) {
            case "C":
                language = ".c";
                break;
            case "Python3":
                language = ".py";
                break;
            case "Java":
                language = ".java";
                break;
        }
        String filePath = path + code.userID + language;
        FileTool.writeFile(filePath, code.data);


        Optional<User> userQuery = userRepository.findById(code.userID);
        if (userQuery.isPresent()) {
            User user = userQuery.get();
            switch (code.language) {
                case "C":
//                    return testC(filePath);
                    return playGameC(user);
            }
            return Result.success();

        } else {
            return Result.error(404, "not found given user");
        }
    }

    private Result playGameC(User user) {
        GameMgrInterface mgr = new PlaneGameMgr(3, Collections.singletonList(user));
        GameRunner runner = new GameRunner(mgr);
        try {
            return Result.success(runner.run());
        } catch (InterruptedException e) {
            // TODO handle error
            e.printStackTrace();
            return Result.error(400, e.getMessage());
        }
    }

    private Result testC(String filePath) {
        try {
            System.out.println("gcc -o textC " + filePath);
            Process process = Runtime.getRuntime().exec("gcc -o textC " + filePath);
            process.waitFor();
        } catch (Exception e) {
            return Result.error(203, e.toString());
        }
        try {
            Process process = Runtime.getRuntime().exec("./textC");
            BufferedReader input =
                new BufferedReader(new InputStreamReader(process.getInputStream()));
            List<String> context = new ArrayList<>();
            String line;
            while ((line = input.readLine()) != null) {
                context.add(line);
            }
            return Result.success(context);
        } catch (Exception e) {
            return Result.error(203, e.toString());
        }
    }
}
